package com.dzsw.netty.unsafe;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;

public class DirectMomeryDemo {

    private static int value = 0;
    private static AtomicInteger atomicInteger = new AtomicInteger(0);
    public static int v = 0;

    public static void main(String[] args) throws Exception {
//        actionMemory();
        counter();
    }

    public static void counter() throws Exception {
        // CAS compare and swap
        ExecutorCompletionService<Integer> completionService =
                new ExecutorCompletionService<>(Executors.newFixedThreadPool(100));

        for (int i = 0; i < 100; i++) {
            completionService.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    for (int i = 0; i < 1000; i++) {
                        value = value + 1;
                        int v = atomicInteger.incrementAndGet();
                        DirectMomeryDemo.v = v;
                    }
                    return null;
                }
            });
        }

        for (int i = 0; i < 100; i++) {
            Future<Integer> future = completionService.take();
            future.get();
        }

        System.out.println("最后的结果" + value + ":" + atomicInteger.get() + ":" + DirectMomeryDemo.v);
    }

    public static void actionMemory() {
        Unsafe unsafe = reflectGetUnsafe();

        //分配10个字节的内存，返回值为内存基础地址
        long address = unsafe.allocateMemory(10);

        //传入基础地址，长度10,  byte-0，初始化堆外内存
        unsafe.setMemory(address, 10L, (byte) 0);

        //传入内存地址位置设置byte值
        unsafe.putByte(address, (byte) 1);
        unsafe.putByte(address + 1, (byte) 2);
        unsafe.putByte(address + 2, (byte) 4);

        //根据内存地址获取byte值
        System.out.println(unsafe.getByte(address));
        System.out.println(unsafe.getByte(address + 1));
        System.out.println(unsafe.getByte(address + 2));

        //释放内存
        unsafe.freeMemory(address);
    }

    //反射拿到Unsafe对象
    private static Unsafe reflectGetUnsafe() {
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            return (Unsafe) field.get(null);
        } catch (Exception e) {
            return null;
        }
    }
}
